<script lang="ts" setup>
import { getToken } from '@/utils/auth';
import axios from 'axios';
import { computed, onMounted, ref, watch } from 'vue';
import { Message } from '@arco-design/web-vue';

const props = withDefaults(
  defineProps<{
    modelValue?: string | number;
    limit?: number;
    fileType?: any;
  }>(),
  {
    modelValue: '',
    limit: 1,
    fileType: ['image/jpeg', 'image/png'],
  }
);

const visible = ref(false);

const emit = defineEmits(['success', 'update:modelValue']);

const imgList = ref<any>([]);

const action = computed(() => {
  return `${import.meta.env.VITE_API_BASE_URL}/file/upload`;
});

const handleSuccess = async (res: any) => {
  const response: any = await axios.post(`${import.meta.env.VITE_API_BASE_URL}/file/create`, {
    name: res.file.name,
    url: res.response.data.url,
    type: res.file.type,
  });
  if (response.code === 20000) {
    emit('success', response);
    if (props.limit === 1) {
      imgList.value[0] = {
        uid: response.data.id,
        name: response.data.name,
        url: response.data.url,
      };
    } else {
      imgList.value.push({
        uid: response.data.id,
        name: response.data.name,
        url: response.data.url,
      });
    }
    emit('update:modelValue', imgList.value.map((i: any) => i.uid).join(','));
  }
};

const onChange = (imgList: any, currentFile: any) => {
  emit('update:modelValue', imgList.map((i: any) => i.uid).join(','));
};

const onProgress = (currentFile: any) => {
  // file.value = currentFile;
};


const fetchData = async (value: any) => {
  if (value) {
    const { data } = await axios.post(`${import.meta.env.VITE_API_BASE_URL}/file`, {
      id: `in,${value}`,
    });
    imgList.value = [...data.map((item: any) => ({ uid: item.id, name: item.name, url: item.url }))];
  }
};

const handleBeforeUpload = (file: any): any => {
  return new Promise((resolve, reject) => {
    if (!props.fileType.includes(file.type)) {
      const fileType = props.fileType
        .map((item: any) => {
          return item.split('/')[1];
        })
        .join('/');
      Message.error(`文件类型不正确，请上传${fileType}格式的文件！`);
      return reject('cancel');
    }
    resolve(true);
  });
};

watch(
  () => props.modelValue,
  (newVal: any, oldVal: any) => {
    if (newVal.toString().indexOf('-') === -1) {
      if (newVal !== oldVal && newVal) fetchData(newVal);
    }
  }
);

onMounted(async () => {
  fetchData(props.modelValue);
});
</script>

<template>
  <a-upload v-bind="$attrs" :action="action" :file-list="imgList" @success="handleSuccess" @change="onChange"
    v-if="limit > 1"></a-upload>
  <a-upload v-bind="$attrs" :action="action" :file-list="imgList" :show-file-list="false" v-if="limit === 1"
    @change="onChange" @progress="onProgress" @success="handleSuccess" @before-upload="handleBeforeUpload">
    <template #upload-button>
      <div
        :class="`arco-upload-list-item${imgList[0] && imgList[0].status === 'error' ? ' arco-upload-list-item-error' : ''}`"
        style="margin-top: 0">
        <div class="arco-upload-list-picture custom-upload-avatar" v-if="imgList[0] && imgList[0].url">
          <img :src="imgList[0].url" />
          <div class="arco-upload-list-picture-mask">
            <a-space size="medium">
              <IconEye @click.stop="visible = true" />
              <IconEdit />
            </a-space>
          </div>
          <a-progress v-if="imgList[0].status === 'uploading' && imgList[0].percent < 100" :percent="imgList[0].percent"
            type="circle" size="mini" :style="{
              position: 'absolute',
              left: '50%',
              top: '50%',
              transform: 'translateX(-50%) translateY(-50%)',
            }" />
        </div>
        <div class="arco-upload-picture-card" v-else>
          <div class="arco-upload-picture-card-text">
            <IconPlus />
          </div>
        </div>
        <a-image-preview :src="imgList[0]?.url" v-model:visible="visible" />
      </div>
    </template>
  </a-upload>
</template>
